import typeOfUtils from '../../utils/type-of-utils'
import empty from "./img/empty";
import {SelectObject} from "./index.vue.d";
import {CreateElement} from "vue/types/vue";
import {VNode} from "vue";
import {VNodeData} from "vue/types/vnode";

export default class RenderUtils {
  static renderShowSlot(vm: SelectObject, createElement: CreateElement) {
    if (vm.$scopedSlots.showSlot) {
      return vm.$scopedSlots.showSlot({
        disabled: vm.disabled,
        showFunc: () => {
          if (!vm.disabled) {
            vm.dragDialogShow = true
          }
        }
      })
    }
    return []
  }

  static renderButton(vm: SelectObject, createElement: CreateElement): VNode[] {
    const result: VNode[] = []
    const button = createElement('el-button', {
      props: {
        disabled: vm.disabled
      },
      on: {
        click: () => {
          if (!vm.disabled) {
            vm.dragDialogShow = true
          }
        }
      }
    }, vm.placeholder)
    result.push(button)
    return result
  }

  static renderInput(vm: SelectObject, createElement: CreateElement) {
    const input = createElement('el-input', {
      props: {
        suffixIcon: 'el-icon-search',
        disabled: vm.disabled,
        value: vm.inputShowValue,
        validateEvent: false,
        readonly: true
      },
      attrs: {
        placeholder: vm.placeholder
      },
      nativeOn: {
        click: (event) => {
          if (!vm.disabled) {
            vm.dragDialogShow = true
          }
          event.stopPropagation()
        }
      }
    })
    return [input]
  }

  static renderSelect(vm: SelectObject, createElement: CreateElement) {
    const result: VNode[] = []
    const submitBtn = createElement('el-button', {
      props: {
        type: 'primary',
        disabled: vm.disabled,
        size: 'small'
      },
      on: {
        click: () => {
          if (!vm.disabled) {
            vm.dragDialogShow = false
            if (vm.selectMultiple) {
              vm.$emit('confirm', vm.selectData)
            } else {
              if (typeOfUtils.isNotEmpty(vm.selectData)) {
                vm.$emit('confirm', vm.selectData[0])
              } else {
                vm.$emit('confirm', {})
              }
            }
            if (vm.clearSelectObjects) {
              vm._clearSelect()
            }
          }
        }
      }
    }, '确定')
    const footer = createElement('div', {
      slot: 'footer'
    }, [submitBtn])
    let row: VNode
    // @ts-ignore
    let top: VNode = null

    if (vm.layout == 'left-right') {
      row = createElement('el-row', {
        props: {
          gutter: 20
        },
        staticClass: 'select-content'
      }, [...RenderUtils.renderLeft(vm, createElement), ...RenderUtils.renderRight(vm, createElement)])
    } else { // 默认是 top-left-right
      // 添加布局
      row = createElement('el-row', {
        props: {
          gutter: 20
        },
        staticClass: 'select-content'
      }, [...RenderUtils.renderLeft(vm, createElement), ...RenderUtils.renderRight(vm, createElement)])
      top = createElement('el-row', {
        props: {
          gutter: 20
        },
        staticClass: 'select-content'
      }, [...RenderUtils.renderSearchForm(vm, createElement)])
    }
    result.push(...RenderUtils.renderDialog(vm, createElement, vm.layout === 'left-right' ? [row, footer] : [top, row, footer]))
    return result
  }

  static renderDialog(vm: SelectObject, createElement: CreateElement, children: VNode[]): VNode[] { // 渲染对话框
    const dragDialog = createElement('el-dialog', { // 对话框
      props: {
        visible: vm.dragDialogShow,
        appendToBody: true,
        ...vm.$attrs,
        title: vm.title,
        width: vm.width,
        top: '1vh'
      },
      class: {
        'select-object-dialog': true
      },
      on: {
        'update:visible': (val) => {
          vm.dragDialogShow = val
        },
        closed: () => {
          if (vm.clearSelectObjects) {
            vm._clearSelect()
          }
          if (vm.clearFormData) {
            vm.$refs.DynamicFormRef?.resetValue()
          }
          vm.dialogOpend = false
        },
        opened: () => {
          if (!vm.dialogOpend) {
            vm.dialogOpend = true
            if (vm.clearFormDataInOpened) {
              vm.$refs.DynamicFormRef?.resetValue()
            }
            if (vm.showLoadAgain) {
              vm.initTableData()
            }
          }
        }
      }
    }, children)
    return [dragDialog]
  }

  static renderSearchForm(vm: SelectObject, createElement: CreateElement): VNode[] {
    const result: VNode[] = []
    const resetBtn = createElement('el-button', {
      props: {
        icon: 'el-icon-refresh'
      },
      on: {
        click: () => {
          vm.$refs.DynamicFormRef?.resetValue()
          vm.initTableData()
        }
      }
    }, '重置')
    const searchBtn = createElement('el-button', {
      props: {
        type: 'primary',
        icon: 'el-icon-search'
      },
      on: {
        click: () => {
          vm.initTableData()
        }
      }
    }, '查询')
    const btns = createElement('el-form-item', {
      props: {
        labelWidth: '40px',
        label: ' '
      }
    }, [searchBtn, resetBtn])
    const form = createElement('DynamicForm', {
      ref: 'DynamicFormRef',
      props: {
        value: vm.searchForm,
        formConfig: vm.formConfig
      },
      staticClass: 'DynamicForm',
      attrs: {
        disabled: vm.disabled
      },
      on: {
        'update:formConfig': (val) => {
          vm.formConfig = val
        },
        'update:value': (val) => {
          vm.searchForm = val
        },
        '~hook:mounted': () => { // 监听子组件钩子
          if (!vm.showLoadAgain) {
            vm.initTableData()
          }
        },
        selectChange: () => {
          vm.initTableData()
        }
      },
      nativeOn: {
        keydown: (event) => {
          if (event.keyCode === 13) {
            vm.initTableData()
          }
          // 阻止 事件冒泡
          event.stopPropagation()
        }
      }
    }, [btns])
    result.push(form)
    return result
  }

  static renderTable(vm: SelectObject, createElement: CreateElement): VNode[] { // 渲染表格
    const result: VNode[] = []
    const config: VNodeData = {
      ref: 'DynamicTableRef',
      props: {
        showIndex: vm.showIndex,
        indexConfig: {
          ...vm.indexConfig,
          index: (index) => {
            if (typeOfUtils.isFunction(vm.indexConfig.index)) {
              // @ts-ignore
              return vm.indexConfig.index(index)
            }
            if (vm.indexConfig?.indexFirstNumber) {
              return index + 1 + vm.indexConfig.indexFirstNumber
            } else {
              return index + 1 + (vm.page.pageNum - 1) * vm.page.pageSize
            }
          },
        },
        select: !vm.disabled,
        selectMultiple: vm.selectMultiple,
        tableConfig: vm.tableConfig,
        data: vm.tableData,
        'max-height': vm.tableHeight,
        selectConfig: vm.selectConfig
      },
      staticClass: vm.total <= 0 ? '' : 'DynamicTable',
      on: {
        'selection-change': (val = []) => {
          if (vm.selectMultiple) {
            if (vm.oldSelectData.length > val.length) { // 说明有移除
              vm.oldSelectData.forEach(delItem => { // 查找移除的值
                const find = val.find(item => {
                  return vm.selectEquals(delItem, item)
                })
                if (!find) { // 找到移除的值
                  const findIndex = vm.selectData.findIndex(i => vm.selectEquals(i, delItem))
                  if (findIndex > -1) {
                    vm.selectData.splice(findIndex, 1)
                  }
                }
              })
            } else {
              const result = vm.selectData
              val.forEach(item => {
                const find = vm.selectData.find(i => {
                  return vm.selectEquals(i, item)
                })
                if (!find) {
                  result.push(item)
                }
              })
              vm.selectData = result
            }
            vm.oldSelectData = val
          } else {
            vm.selectData = val
          }
        }
      },
      directives: [
        {
          name: 'loading',
          value: vm.loading
        }
      ]
    }
    if (typeOfUtils.isFunction(vm.tableMergeConfig)) {
      const mergeTable = vm.getTableMergeConfig?.mergeTable
      if (typeOfUtils.isNotEmpty(mergeTable)) {
        // @ts-ignore
        config.props.data = mergeTable
      }
      const newOn = vm.getTableMergeConfig?.tableEvent
      if (typeOfUtils.isNotEmpty(newOn)) {
        vm.$set(config, 'on', newOn)
      }
      const getAttrsSomFunc = (name) => {
        const func = vm.getTableMergeConfig?.[name]
        if (typeOfUtils.isFunction(func)) {
          // @ts-ignore
          vm.$set(config.props, name, func)
          vm.$set(config, 'attrs', {...config.attrs, [name]: func})
        }
      }
      getAttrsSomFunc('spanMethod')
      getAttrsSomFunc('rowClassName')
      getAttrsSomFunc('cellClassName')
    }
    const table = createElement('DynamicTable', config)
    result.push(table)
    return result
  }

  static renderLeft(vm: SelectObject, createElement: CreateElement): VNode[] { // 渲染左边布局
    const result: VNode[] = []
    let layoutSpan = vm.layout == 'left-right' ? [
      ...RenderUtils.renderSearchForm(vm, createElement),
      ...RenderUtils.renderTable(vm, createElement),
      ...RenderUtils.renderPagination(vm, createElement)] : [
      ...RenderUtils.renderTable(vm, createElement),
      ...RenderUtils.renderPagination(vm, createElement)]
    const left = createElement('el-col', {
      props: {
        span: 18
      }
    }, layoutSpan)
    result.push(left)
    return result
  }

  static renderRight(vm: SelectObject, createElement: CreateElement): VNode[] { // 渲染右边布局
    const result: VNode[] = []
    const children: VNode[] = []
    if (vm.$scopedSlots.rightSlot) {
      // @ts-ignore
      children.push(...vm.$scopedSlots['rightSlot'](vm.selectData, vm.tableData))
    } else {
      children.push(...RenderUtils.renderFilterInput(vm, createElement))
    }
    const right = createElement('el-col', { // el-scrollbar 滚动条
      props: {
        span: 6
      },
      staticClass: 'rightContent',
    }, children)
    result.push(right)
    return result
  }

  static renderPagination(vm: SelectObject, createElement: CreateElement): VNode[] { // 渲染分页器
    if (vm.total <= 0) {
      return []
    }
    const result: VNode[] = []
    if (!vm.disabled) {
      let pageSizes = [10, 20, 50, 100]
      let pageSize = vm.page.pageSize
      if (typeOfUtils.isFunction(vm.tableMergeConfig)) {
        const newPageSizes = vm.getTableMergeConfig?.pageSizes
        if (typeOfUtils.isNotEmpty(newPageSizes)) {
          pageSizes = newPageSizes
        }
        const newPageSize = vm.getTableMergeConfig?.pageSize
        if (typeOfUtils.isNotEmpty(newPageSize)) {
          pageSize = newPageSize
        }
      }
      const item = createElement('el-pagination', {
        props: {
          pageSizes,
          pageSize,
          layout: 'total, ->, sizes, prev, pager, next, jumper',
          total: vm.total,
          background: true
        },
        on: {
          'update:currentPage': (val) => {
            if (!val) {
              return
            }
            if (vm.page.pageNum !== val) {
              vm.page.pageNum = val
              vm.initTableData()
            }
          },
          'size-change': (val) => {
            vm.page.pageSize = val
            vm.initTableData()
          }
        }
      })
      result.push(item)
    }
    return result
  }

  static renderFilterInput(vm: SelectObject, createElement: CreateElement): VNode[] {
    const result: VNode[] = []
    let height = 0
    if (vm.selectMultiple) {
      height += 64
      const count = createElement('div', {}, [`已选（${vm.showSelectData.length}）`])
      const clearBtn = createElement('el-button', {
        props: {
          type: 'text'
        },
        on: {
          click: () => {
            vm._clearSelect()
          }
        }
      }, [`清空`])
      const selectClear = createElement('div', {
        staticClass: 'resultCount'
      }, [count, clearBtn])
      result.push(selectClear)
      const input = createElement('el-input', {
        props: {
          value: vm.filter,
          clearable: true,
          size: 'small',
          'suffix-icon': 'el-icon-search'
        },
        staticClass: 'filterInput',
        attrs: {
          placeholder: vm.rightPlaceholder
        },
        on: {
          input: (val) => {
            vm.filter = val
          }
        }
      })
      result.push(input)
    } else {
      height += 64
      const count = createElement('div', {}, [`单选（${vm.showSelectData.length}）`])
      const clearBtn = createElement('el-button', {
        props: {
          type: 'text'
        },
        on: {
          click: () => {
            vm._clearSelect()
          }
        }
      }, [`清空`])
      const selectClear = createElement('div', {
        staticClass: 'resultCount'
      }, [count, clearBtn])
      result.push(selectClear)
    }
    const scoll = createElement('el-scrollbar', {
      style: {
        height: 'calc(100% - ' + height + 'px)'
      },
    }, RenderUtils.renderSelectResult(vm, createElement))
    result.push(scoll)
    return result
  }

  static renderSelectResult(vm: SelectObject, createElement: CreateElement) {
    if (typeOfUtils.isEmpty(vm.showSelectData)) {
      const img = createElement('el-image', {
        props: {
          src: empty
        }
      })
      return [img]
    }
    return vm.showSelectData.map((i, index) => {
      return createElement('el-tag', {
        slot: 'default',
        props: {
          closable: !vm.disabled,
          effect: "plain"
        },
        directives: [
          {
            name: 'ShowTooltip',
            value: vm.selectShowView(i)
          }
        ],
        on: {
          close: () => { // 删除
            const showDelItem = vm.showSelectData[index]
            let delItems: any[]
            if (typeOfUtils.isFunction(vm.tableMergeConfig)) {
              delItems = vm.getTableMergeConfig.deleteShowSelectData(showDelItem, vm.selectData)
            } else {
              const findIndex = vm.selectData.findIndex(i => vm.selectEquals(i, showDelItem))
              delItems = vm.selectData.splice(findIndex, 1)
            }
            const table = vm.$refs.DynamicTableRef
            if (vm.selectMultiple) {
              delItems.forEach(delItem => {
                const row = vm.tableData.find(i => vm.selectEquals(i, delItem))
                if (row) {
                  table.$refs.elTableRef.toggleRowSelection(row)
                }
              })
            } else {
              table.zhixinRadio = undefined
            }
          }
        }
      }, vm.selectShowView(i) as string)
    })
  }
}
